import bus from './bus'
import merge from './merge'
export default {
  install(Vue, params = {}) {
    const dialogStart = {
      left: 0,
      top: 0
    }
    let enterAnimationQueue = []
    $('body').on('click', function (evt) {
      dialogStart.left = evt.clientX
      dialogStart.top = evt.clientY
      enterAnimationQueue.forEach((fn) => {
        fn()
      })
      enterAnimationQueue = []
    })
    function enterAnimation(el) {
      return function () {
        {
          let $el = $(el)
          let pos = $el.position()
          let time = 300
          el.enterTop = dialogStart.top
          el.enterLeft = dialogStart.left
          $el.css({
            opacity: 0,
            top: dialogStart.top,
            left: dialogStart.left,
            transform: 'scale(0)',
            transformOrigin: 'top left'
          })
          setTimeout(() => {
            $el.css({
              transition: 'all ' + time / 1000 + 's',
              opacity: 1,
              top: pos.top,
              left: pos.left,
              transform: 'scale(1)'
            })
          }, 0)
          setTimeout(() => {
            $el.css({
              transition: ''
            })
          }, time)
        }
      }
    }
    function leaveAnimation(instance, fn) {
      let $el = $(instance.$el)
      let time = 300
      $el.css({
        transition: 'all ' + time / 1000 + 's',
        opacity: 0,
        top: instance.$el.enterTop,
        left: instance.$el.enterLeft,
        transform: 'scale(0)',
        transformOrigin: 'top left'
      })
      setTimeout(() => {
        $el.css({
          transition: ''
        })
        fn();
      }, time)
    }
    const { store, router } = params
    const eventBus = Vue.prototype.$bus || new Vue()
    Vue.prototype.$modal = {
      ...bus,
      dialog(componentName = '', dialogOptions = {}, componentOptions = {}) {
        const that = this
        let Cotr = Vue.extend({
          store,
          router,
          render(h) {
            dialogOptions.on = merge(
              {
                confirm(val) {
                  that.emit('confirm', val)
                  eventBus.$emit('modal-closed', instance)
                  leaveAnimation(instance, () => {
                    instance.$destroy()
                    document.body.removeChild(instance.$el)
                  })
                },
                cancel(action) {
                  that.emit('cancel', action)
                  eventBus.$emit('modal-closed', instance)
                  leaveAnimation(instance, () => {
                    instance.$destroy()
                    document.body.removeChild(instance.$el)
                  })
                },
                'update:visible': function (b) {
                  let [dialog] = instance.$children
                  dialog.visible = b
                }
              },
              dialogOptions.on || {}
            )
            componentOptions.on = merge(
              {
                confirm(val) {
                  that.emit('confirm', val)
                  eventBus.$emit('modal-closed', instance)
                  leaveAnimation(instance, () => {
                    instance.$destroy()
                    document.body.removeChild(instance.$el)
                  })
                },
                cancel(action) {
                  that.emit('cancel', action)
                  eventBus.$emit('modal-closed', instance)
                  leaveAnimation(instance, () => {
                    instance.$destroy()
                    document.body.removeChild(instance.$el)
                  })
                }
              },
              componentOptions.on || {}
            )
            const comp = h(componentName, componentOptions)
            const dialog = h(
              'TmDialog',
              merge(
                {
                  props: {
                    visible: true
                  },
                  scopedSlots: {
                    default: (props) => comp
                  }
                },
                dialogOptions
              )
            )
            return dialog
          },
          mounted() {
            Vue.nextTick(() => {
              // dialog 进入动画, 从点击处放大
              enterAnimationQueue.push(enterAnimation(instance.$el))
            })
          }
        })
        let instance = new Cotr().$mount()
        instance.$on('hook:mounted', () => {})
        document.body.appendChild(instance.$el)
        eventBus.$emit('modal-created', instance)
        return that
      },
      drawer(componentName = '', dialogOptions = {}, componentOptions = {}) {
        const that = this
        let Cotr = Vue.extend({
          store,
          router,
          render(h) {
            dialogOptions.on = merge(
              {
                confirm(val) {
                  that.emit('confirm', val)
                  eventBus.$emit('modal-closed', instance)
                  instance.$destroy()
                  document.body.removeChild(instance.$el)
                },
                cancel(action) {
                  that.emit('cancel', action)
                  eventBus.$emit('modal-closed', instance)
                  instance.$destroy()
                  document.body.removeChild(instance.$el)
                }
              },
              dialogOptions.on || {}
            )
            componentOptions.on = merge(
              {
                confirm(val) {
                  that.emit('confirm', val)
                  eventBus.$emit('modal-closed', instance)
                  instance.$destroy()
                  document.body.removeChild(instance.$el)
                },
                cancel(action) {
                  that.emit('cancel', action)
                  eventBus.$emit('modal-closed', instance)
                  instance.$destroy()
                  document.body.removeChild(instance.$el)
                }
              },
              componentOptions.on || {}
            )
            const comp = h(componentName, componentOptions)
            const dialog = h(
              'TmDrawer',
              merge(
                {
                  props: {
                    visible: true
                  },
                  on: {
                    'update:visible': function (v) {
                      dialog.componentInstance.visible = v
                      setTimeout(() => {
                        that.emit('cancel', 'close')
                        eventBus.$emit('modal-closed', instance)
                        instance.$destroy()
                        document.body.removeChild(instance.$el)
                      }, 300)
                    }
                  },
                  scopedSlots: {
                    default: (props) => comp
                  }
                },
                dialogOptions
              )
            )
            return dialog
          }
        })
        let instance = new Cotr().$mount()
        document.body.appendChild(instance.$el)
        // 写一个进入动画
        const transform = 'translate(-110%, 0)'
        const transform2 = 'translate(0, 0)'
        instance.$el.style.transition = 'all 0.3s cubic-bezier(0.19, 1, 0.22, 1)'
        instance.$el.style.transform = transform
        setTimeout(() => (instance.$el.style.transform = transform2), 200)
        setTimeout(() => {
          instance.$el.style.transform = ''
          instance.$el.style.transition = ''
        }, 500)
        eventBus.$emit('modal-created', instance)
        return that
      },
      modal(componentName, componentOptions = {}) {
        const that = this
        const gen = () => {
          let Cotr = Vue.extend({
            store,
            router,
            render(h) {
              componentOptions.on = merge(
                {
                  confirm(val) {
                    that.emit('confirm', val)
                    eventBus.$emit('modal-closed', instance)
                    instance.$destroy()
                    document.body.removeChild(instance.$el)
                  },
                  cancel(action) {
                    that.emit('cancel', action)
                    eventBus.$emit('modal-closed', instance)
                    instance.$destroy()
                    document.body.removeChild(instance.$el)
                  }
                },
                componentOptions.on || {}
              )
              const comp = h(componentName, componentOptions)
              return comp
            }
          })
          let instance = new Cotr().$mount()
          document.body.appendChild(instance.$el)
          console.log('modal-created', instance)
          eventBus.$emit('modal-created', instance)
        }
        if (componentOptions.isSingle) {
          eventBus.$once('try-open-instance-back', (has) => {
            console.log('has', has)
            if (!has) {
              gen()
            }
          })
          eventBus.$emit('try-open-instance', componentOptions)
        } else {
          gen()
        }
        return that
      }
    }
  }
}
